Release v4.0.0#52
Merged
Merged
Conversation
…ing tests) Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
fix(ui): global-event binder no-DOM guard (v3.4.3) + hardening tests
Proves the keyed per-item components are SSR-compatible (all rows present), so a MapKeyedComponent list can be server-rendered and hydrated. No bug found. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
StyleBlock lists css.Global/css.Root registry keys (g-...) alongside hashed classes, and Seed suppresses re-emission on hydration — so global/token rules are not re-injected client-side (no FOUC/duplication). No bug found. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…build
state/example_test.go (//go:build js && wasm) and the build-neutral
state/useatom_example_test.go both declared func ExampleUseAtom, so under the
wasm build the whole state package test binary failed to compile ("redeclared").
The wasm-only file was a redundant, never-executed (no Output:) duplicate; remove
it. The documented build-neutral example remains for all builds. Found by a
whole-module `GOOS=js GOARCH=wasm go vet` sweep.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
fix(state): wasm test-build duplicate ExampleUseAtom (v3.4.4) + SSR hardening
…r refs
WriteHTTPError is //go:build !js (native HTTP helper), but build-neutral test
files referenced it, so the diagnostics and internal/diagnostics test binaries
failed to compile under GOOS=js GOARCH=wasm ("undefined: WriteHTTPError"). Tag
the HTTP-dependent test files //go:build !js to match, and split the HTTP
benchmark into a native-only file (keeping the build-neutral NewReport
benchmark). Found by a full-module wasm `go vet` sweep; same class as the v3.4.4
state fix.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
fix(diagnostics): wasm test-build broken by native-only WriteHTTPError (v3.4.5)
476k+ executions found no panic or invariant violation: non-empty input yields non-empty output, SelectorID == "#"+escape, and colons are always escaped (G29). The seed corpus runs on every `go test`. No bug found. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
hardenCSS skipped NUL inline, AFTER its lookahead guards. An input like "*\x00/" or "<\x00/style>" therefore slipped past the guards (which saw the NUL, not the dangerous next byte) and then had the NUL removed — silently reconstituting "*/" or "</style>" in the emitted CSS, a style-element/comment breakout. Strip NULs in a separate first pass so the guards run on the final byte stream. Found by FuzzInjectHardening (fuzzing css.Inject). Re-fuzzed 1.8M+ execs with no further bypass; regression seed committed. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
security(css): fix hardenCSS NUL-byte breakout bypass (v3.4.6)
877k+ executions confirm css.Var sanitizes any input to a safe var(--<identifier>) reference — no stray ')' / ';' / '}' / whitespace can break out of the var() call or the declaration. No bug found. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
467k+ executions with precise oracles confirm the sanitized RawHTML path never lets a <script>/<iframe> tag, a quoted on*= event handler, or a javascript: URL survive into the rendered output. No bug found (the fuzz did catch and fix an over-broad oracle in an earlier draft that flagged inert text like "onerror=0"). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
test(css,html): fuzz Var + RawHTML sanitization (security regression coverage)
3.36M+ executions confirm the hashed-class emit path (distinct from Inject) also applies hardenCSS — no </style>, </script>, or */ can be emitted through an arbitrary property value, including the NUL-bypass class fixed in v3.4.6. No bug. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
1.2M+ executions confirm markdown rendering never lets a <script>/<iframe> tag, a quoted on*= handler, or a javascript: href/src survive into the rendered output — covering embedded raw HTML and adversarial link/image URLs. No bug. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
8.5M+ executions confirm folding the same distinct-property rules in any order yields the same content-hashed class and CSS — the build-reproducibility / dedup guarantee. No bug. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
test(css,html): fuzz emit-path/markdown/determinism (hardening)
11.5M+ executions confirm UnmarshalSnapshotJSON never panics on arbitrary bytes and that one Marshal∘Unmarshal cycle reaches a byte-stable fixpoint — the normalizeSnapshot float64->int folding and key ordering never drift a persisted snapshot across save/load. No bug. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…ning test(state): fuzz snapshot round-trip fixpoint + decode robustness
3.8M+ executions confirm RenderBootstrapScript emits exactly one <script and one </script> regardless of attacker-controlled atoms, correlation id, route path, or script id — embedded SSR data can never terminate the script element early. No bug. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
test(ui): fuzz SSR bootstrap script-breakout invariant
…tes (v3.4.7)
The render path emitted URL-bearing attributes (href/src/action/formaction/
poster/object data/xlink:href) verbatim, so a user-controlled URL passed through
the ordinary element API — html.A(html.Props{Href: userURL}) — could ship a
clickable <a href="javascript:alert(1)">, an XSS vector. Only markdown/RawHTML
sanitized URLs before.
Script-executing schemes (javascript:, vbscript:) are now neutralized to the
inert about:blank sentinel at BOTH the SSR serializer (internal/runtime/ssr.go:
serializeSSRAttr + writeSSRProps) and the browser DOM adapter (SetAttribute +
BatchSetAttributes), tolerating whitespace/control-char/CRLF/case obfuscation.
Safe schemes (http(s), data:, mailto, tel), relative paths, and fragments are
untouched; a URL-looking value in a non-URL attribute is left alone.
Shared SanitizeURLAttributeValue exported from internal/runtime; mockdom mirrors
it so the client path is testable natively. Vectors ported from React's
ReactDOMServerIntegrationUntrustedURL suite (TestURLSanitization*) plus
FuzzSanitizeURLAttributeValue (7M+ execs clean).
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
security(render): block javascript:/vbscript: URLs in element attributes (v3.4.7)
Codifies the framework-agnostic subset of React's ReactDOMServerIntegrationAttributes suite as GWC regression tests: boolean coercion (true->bare, false->omitted), nil omission, numeric stringification, and HTML-escaping of values. Adds: - TestAttributeSerializationSemantics + TestAttributeNameValidationRejectsInjection (invalid attr names dropped, #57) - FuzzSerializeSSRAttrBreakout (3.5M+ execs): for any name/value, an accepted attribute is exactly name="escaped" — two quotes, no raw <>, so a value can neither close the attribute early nor inject markup. No bug found; GWC's serializer was already correct. Pure regression lock. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
test(ui,runtime): port React attribute-serialization invariants
Ports React's escapeTextForBrowser guarantee as GWC regression tests: &, <, >, ", ' in any text position (bare Text node, element child, nested child, sibling children) are entity-encoded so a payload can never open a markup tag. - TestTextContentEscaping + TestTextContentMultipleSiblings - FuzzTextNodeNoMarkup (4.5M+ execs): an arbitrary string rendered as a bare Text node never emits a raw < or >. No bug found; GWC's text path was already sound. Pure regression lock. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…form sliver remains)
Closes the last audit item: a flip-demo wasm app (keyed list + shuffle that reorders, each item computing its FLIP invert from measured before/after rects via anim.ComputeFLIP and recording the invert translateY in data-flip-dy) plus a Playwright test (//go:build playwrightgo) that, in real chromium, asserts the keyed reorder (deterministic rotate) AND a non-zero FLIP invert on moved items — proving keyed-list FLIP works in a real browser. The data-flip-dy attribute is persisted (not animated away), so the assertion is not timing-sensitive. Example compiles for wasm; test compiles under -tags playwrightgo and runs in the CI browser lane (built on the repo's proven test/playwrightgo harness). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…it FA4 niggle)
Closes the 'no combined Link* + typed-query constructor' niggle: gwc routes gen now
emits, alongside each path-param Link*, a Link*WithQuery(pathParams..., query
url.Values) that appends search params (pair with router.EncodeQuery for typed
queries) — so path and search params compose in one typed call. Regenerated the
typed-routes-demo; test: LinkUserWithQuery("42", {sort:desc}) == /users/42?sort=desc.
routesgen unit tests updated for the inline-map format + WithQuery assertions.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…A1 niggle) Closes the '.Text live-getter only tested under js && wasm' niggle: a native test renders a signal's reactive text node through runtime+mockdom and asserts the getter (with a custom formatter) produces the value — covering the .Text path off the browser lane. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Implements (not documents) the FA2 ask: a native-lane DOM render test proving UseQuery renders cached data into a real DOM through the reconciler off the browser lane (the snapshot path), complementing the wasm SWR e2e. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Add NewAutoComputed, which discovers its reactive sources by running the compute once with read-tracking on and recording every Signal.Get it observes (Solid-style). Explicit NewComputed stays the default and recommended path (no hidden graph); auto-tracking is an opt-in convenience. Signal.Get gains a single-atomic-load read hook that is a no-op outside a NewAutoComputed discovery pass. Native test proves discovery of both sources + recompute on change. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Update the audit checkbox: auto-tracking is no longer just documented as a design decision — NewAutoComputed ships it as an opt-in sibling of the default explicit NewComputed. Closes the last actionable audit item. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Replace the six-entry stdlib deny-list with a real import-graph pass. It seeds from explicitly client-only (js && wasm) files, follows their imports into local module packages transitively, and classifies every reached path: curated server stdlib, a prefix matcher for well-known third-party server SDKs (gorm/grpc/AWS/GCP/Azure/Mongo/pgx/redis/k8s/…), and local packages that are themselves constrained off js/wasm. Closes the audit gap where gorm/grpc/cloud SDKs imported into a browser file — directly or through a local helper — passed silently. Diagnostics show the via-chain; dedup keeps one finding per (file, line, leaked path). Source-walked (not go/packages) so the CI gate is deterministic/offline. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
--fix no longer only gofmts. It now applies the deterministic structured Edits diagnostics carry — today the server-leak fix: rewrite a browser file's `//go:build js && wasm` (and legacy +build twin) to `//go:build !js || !wasm`, moving the file and its server-only imports out of the client bundle. The fixer loops to a fixed point, re-gofmts, and reports applied vs still-manual remediations (hook-outside-component is honestly surfaced as manual, since hoisting a hook can't be rewritten safely). This is the AI-native post-edit loop AGENTS.md documents: an agent that imports database/sql or gorm into a browser file runs --fix and the file moves server-side, not just reformatted. Idempotent. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Add localfirst.Text, an RGA (Replicated Growable Array) for shared-doc editing. Each character is an immutable id'd element inserted after another; deletions are tombstones; Merge unions element sets with deleted-wins; a deterministic id-ordered DFS from the head converges every replica regardless of edit/merge order. Concurrent insertions — including at the same position — both survive, closing the LWW gap the PN-Counter (integers only) could not cover for text. Export/RestoreText serialize the op log. Tests prove concurrent-edit convergence, same-position survival, commutativity/idempotence, and round-trip. Also marks Tier 0 (FB1/FB3/FC6) done in the plan. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Remove continue-on-error from the supply-chain vuln job so govulncheck blocks merges. To keep the gate meaningful rather than perpetually red on un-fixable toolchain CVEs, gwc vuln now classifies stdlib/toolchain advisories: reachable DEPENDENCY advisories always block; reachable stdlib advisories are reported but waived by default (fix = bump Go), gateable with -include-stdlib. A reachable dependency advisory still blocks even alongside a waived stdlib one. 3 new tests. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
gwc doctor --fix now auto-applies the deterministic remediations doctor would only print: the structured source edits shared with check --fix (server-leak build-constraint rewrite) and generating a minimal gwc-start.json for a hand-built app (main.go present, metadata absent), never overwriting existing metadata. Non-deterministic prerequisites (Go missing, busy port) remain reported. Adds doctor-parity.yml running the doctor/check-fixer tests + a gwc doctor smoke on ubuntu/macos/windows. 2 tests. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…4, Tier2 FA5) Router (wasm): navigation now wraps the DOM swap in the View Transitions API by default (auto-skipped under prefers-reduced-motion; opt-out via SetViewTransitions) and moves keyboard focus to the new route content ([autofocus]/[data-route-focus], else the container with tabindex=-1; opt-out via SetFocusManagement). The >90% route-change case animates and is screen-reader-correct with zero caller wiring. gwc lint: new non-browser a11y linter (gwc-a11y) parses HTML with x/net/html and flags missing alt, no accessible name on buttons/links, unlabeled form controls, missing <html lang>, and positive tabindex — no false positives on accessible markup; each finding carries the rule as Symbol + a source line. Complements the browser-only axe gate. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…2 FA1) createReactiveTextNode now takes the full source-id set and stores them comma-joined in the atom-id prop; the reconciler splits them and wires a fine-grained subscription per dependency. ComputedSignal.Text passes all declared sources instead of only the first, so a multi-source computed's text flushes when ANY dependency changes — closing the silent missed-update footgun. Native test proves both the structural id set and the rendered value. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…6, FA2) FA6: ui.DeferState/DeferStatus + RenderDefer (pure block router) + UseAsyncDefer give ui.Defer Angular @defer's four blocks — placeholder/loading/content/error — instead of a boolean latch. The trigger runs the async loader once and routes to the matching block. RenderDefer is unit-tested for every state and nil-block safety. FA2: fetch.UseDurableMutation bridges the optimistic query cache and the durable offline MutationQueue (previously disconnected). One call: enqueue durably → optimistic cache update → background commit; success clears the queue + commits authoritatively, failure rolls back and keeps the entry for Replay. Lives in fetch to avoid the ui import cycle. 2 native tests. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
gwc mcp now publishes a first-class read-only gwc_agentui_catalog tool in tools/list, and tools/call returns the agentui allow-list (component names + permitted prop keys) as JSON. An agent can query exactly which components and props it may emit before generating a UI tree, turning the allow-list from after-the-fact rejection into up-front guidance. 3 tests cover manifest inclusion, result shape, and end-to-end JSON-RPC dispatch. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Add SuspenseStories (fallback-while-pending → resolved-content) and HydrationBoundaryStories (a progressive-hydration island in every strategy: immediate/visible/interaction/idle) plus an AllStories aggregate. All four boundary surfaces now mount through the real reconciler in the stories-as-tests pass, completing the workbench's stated boundary coverage. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
… B4) Add a table-driven completeness matrix that folds every utility category (display/flex/spacing/sizing/color/typography/radius/effects/variants/ responsive/important) through the registry end-to-end, asserting each emits a real class + CSS — a silently-dropped category now fails CI. Add a no-double-emit test proving an identical utility set folds to one class emitted exactly once. Document the Raw/Sel escape hatches as registry-managed (content-hashed, SSR-reused), not unmanaged inline. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
gwc bench -fail-on-regression now exits non-zero when any benchmark regressed beyond the 2% tolerance vs the committed baseline, turning the existing per-benchmark comparison into a real merge gate. New bench-drift.yml runs it on PRs at -parallel 1 for low noise. Gate logic unit-tested for all four cases (enabled+regressed, disabled, clean, no baseline). Honest scope: the amd64 selector regression is not root-caused here (this env is ARM64 Windows and cannot reproduce the amd64 numbers); the gate is what will surface and pin it on amd64 CI. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
The release job now cross-compiles gwc (pure-Go, CGO disabled, trimpath + -s -w) for linux/macOS/windows × amd64/arm64, attaches them to the GitHub release with a single SHA256SUMS manifest, and attests build provenance for the binaries — so users skip a from-source build. All targets verified to cross-compile cleanly. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Wire WAI-ARIA arrow-key roving into the tabs template — Left/Right wrap, Up/Down, Home/End — via a pure, unit-tested tabsNextIndex helper. Add catalog-smoke.yml: per component, scaffold a throwaway module with a replace directive, `gwc add` it, and `go build` (real copy-into-module → build). Add a fast offline guard that renders every catalog entry and parses it as valid Go. Browser axe pass remains a browser-lane follow-up. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…er1 F7) Add ROADMAP.md (Now/Next/Later/Exploring themes + an Ideas-post feedback loop), a Triage SLA table in CONTRIBUTING (security 2d / bug 5d / feature 10d / PR 5d with escalation), a "where to ask vs. file" section, and concrete .github/ISSUE_TEMPLATE/ (structured bug form + config that disables blank issues and routes Q&A/ideas to Discussions and security to the disclosure policy). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
go run ./tools/devtools-extension/pack builds dist/gwc-devtools-<version>.zip — the directly-loadable package (Chrome/ Edge store upload as-is; Firefox Load-Temporary-Add-on; signed .xpi via web-ext sign of the same zip). Uses Go stdlib archive/zip so it adds no node/web-ext dependency, preserving the zero-npm posture; validates the manifest and packages exactly the runtime files. 3 tests. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Add examples/public/third-party-js: wraps the @sindresorhus/slugify ESM module behind a typed Go bridge (interop.ImportModule → SlugifyBridge with Call/type-assert), with a pure-Go fallback so the same call site works on the server. Native-stub parity test runs on the native lane (ImportModule unavailable) and asserts the bridge is unloaded yet still returns the correct slug via the fallback; fallback semantics are table-tested. README documents the dynamic-import → typed-wrapper → Go-fallback pattern. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Add `gwc warm`: a long-running daemon that runs a cold build to populate the Go build cache, then watches the project (reusing the watch fingerprint loop) and re-runs the build on every save so the cache stays hot — the developer's next build hits a warm cache instead of a cold one. -target native|wasm, -once (CI), and -json (cold/warm timing report CI can gate on). Complements gwc buildreport. 4 tests cover build args, the wasm env, failure surfacing, and bad-target rejection. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Ship the V4 branch: server functions (//gwc:server + serverfn), whole-stack one-binary deploy (wholestack), query cache/mutations (query + ui.UseQuery), local-first CRDT sync + presence (localfirst), agent-native generative UI (agentui), time-travel snapshots (timetravel), fine-grained signals (state.Signal), animation engine (anim), named slots, two-way binding, typed search params, and the gwc add/i18n gen/server gen/supplychain/vuln/ buildreport/llms commands. Documentation brought fully to the V4 spec as a merge precursor: - Reference manual: V4 package sections across ch02/04/05/06/07/08/10/11/12/13 - api-browser (ch16): 9 new package sections + symbol rows - Capability matrix: 12 V4 rows, slugs wired to examples - llms.txt/llms-full.txt regenerated - Stale deprecated-API content swept (UseFetch/UseComputed/GetOutlet/etc.) - 13 new public examples authored + wired into the generated catalog CHANGELOG Unreleased -> v4.0.0. Full native test suite green (134/134). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
monstercameron
pushed a commit
that referenced
this pull request
Jul 6, 2026
Two security-policy hardenings for the server-function trust boundary, both secure-by-default and configurable. CSRF (SetCSRFProtection, default on): Handle now requires Content-Type: application/json and rejects browser-flagged cross-site requests. application/json is not a CORS-safelisted content type, so a cross-origin browser call carrying it forces a preflight an attacker's forged page cannot satisfy, and an HTML form (limited to the three safelisted types) cannot forge a call at all. Sec-Fetch-Site: cross-site (a JS-unspoofable, browser-set header, absent for non-browser clients) is rejected outright as defense-in-depth. The generated client always sends application/json, so this is transparent to generated code. Error disclosure: a plain error's text (which can wrap a DSN/SQL/path) is no longer returned to the caller — non-StatusError maps to a generic 500. The real error is delivered to the new SetErrorLogger sink (default stderr) so operators keep full diagnostics. Author-chosen messages still travel via StatusError. Read/decode errors now use generic messages instead of leaking Go type/field names. Pins (all negative-verified): TestHandleRejectsNonJSONContentType, TestHandleAcceptsJSONContentTypeWithCharset, TestHandleRejectsCrossSiteFetch, TestCSRFProtectionToggle, TestHandlePlainErrorIsGenericToClient. Updated the relied-upon TestCallPropagatesServerError / TestStatusForErrorEdgeCases to the new policy and regenerated the API baseline for the two new exported setters. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Ships the V4 branch to main.
Headline V4 features
//gwc:server+serverfn) withgwc server genwholestack)query+ui.UseQuery/UseMutation)localfirst, facepile)agentui)timetravel+ devpanel)state.Signal), animation (anim), named slots, two-way binding, typed search paramsgwccommands:add,i18n gen,server gen,supplychain,vuln,buildreport,llmsDocumentation (merge precursor)
llms.txtregenerated; deprecated-API content sweptVerification
GOPROXY=off)CHANGELOG
Unreleased->v4.0.0 - 2026-06-28.🤖 Generated with Claude Code